# 字符串的定义
# 定义变量
# info1 ="D:\tools\noco"
# info2 ="D:\tools\noco"
# info3 ="D:\\tools\\noco"
# info4 ='张三说："你很厉害"'
# print(info1)
# print(info2)
# print(info3)
# print(info4)

# \n 表示换行
# \t 表示执行TAB
# 问题1：路径想原样输出,在字符串外面添加字母 r，或者在有转义字符的地方添加 \
# 问题2：字符串中本身存在单双引号的情况，需要交叉输入引号


# 字符串的使用 -字符元素查找
# 1.通过位置（下标）找元素
# # 定义变量
# info = "abcdefg"
# # 获取字母d
# print(info[3])
# # print(info[‐4])
# # 2.通过元素找位置（下标）
# # 字母e在哪个位置？
# print(info.find("e"))
# # 字母k在哪个位置？
# print(info.find("k"))


# 字符串替换
# 定义字符串
# info = "金三胖同志被称之为世界最成功的80后，金三胖真牛！"
# # 使用字符串（替换）
# info1 = info.replace("金三胖","马赛克")
# print(info1)
# print(info)
# 结论：
# 字符串不可变数据类型，进行替换操作之后，原有的字符串不发生变化


# 字符串连接
# 定义变量
# info = ['Python', 'Java', 'PHP']
# num = [11, 22, 33]
# info1 = " and ".join(info)
# print(info1)
# print(type(info1))

# print("‐".join(num)) # 序列中如果不是字符元素，报错TypeError: sequence item 0: expected str instance, int found
# 结论：
# 通过连接字符将列表/元组/集合对应字符元素才能连接成字符串


# 字符串拆分-字符串名.split(分割符)
# 定义SQL语句变量
# sql = "SelEct * from student wherr id = 001;"
# # 上述SQL语句按照空格把语句中的单词拆分出来
# print(sql.split())
# # 在上述基础上把每个单词打印出来？
# for i in  sql.split():
#     print(i)
#
# # 上述SQL按照where拆分出来
# print(sql.split("where"))

# 总结
# 1.通过split拆分后，结果是列表类型
# 2.如果split中不输入分隔符，默认按照空格拆分


# 字符串其他操作
# 转大写： 字符串.upper()
# 转小写： 字符串.lower()
# 判断是字母： 字符串.isalpha()
# 判断是数字： 字符串.isdigit()
# 判断某个字符出现的次数： 字符串.count("字符")
# 字符串两头去除空格:变量.strip()

# 1.去除字符串两头的空格
# phone = " 13800000001 "
# print(phone)
# print(phone.strip())
# 2.大小写转换
# 转大写：字符串.upper()
# 转小写：字符串.lower()
# 定义SQL语句变量
# sql = "SelECt * from student where id = 001;"
# # 判断是否是查询（select是否存在）
# if "select" in sql.lower():
#     print("显示查询结果")
# else:
#     print("非查询")


# 列表的定义
# 定义空列表
# info = []
# info1 = list()
# print(info)
# print(info1)

# 定义非空列表
# info2 = [11, "aaa", 1.88]
# print(info2)


# 列表的使用 - 列表元素查询：索引
# 语法格式： 列表名[索引]
# 注意事项：
# 结果返回的是索引（也叫下标）对应列表元素，索引默认从0开始
# 如果查询的索引不存在，则代码会报错
# 列表元素查询
# 定义列表
# name_list = ['张三', '李四', '王五']
# 按照索引查元素
# 查询李四
# print(name_list[1])
# 查询不存在的索引
# print(name_list[4])
# 总结：如果查询的下标（索引）不存在，则代码报错【索引超出了范围】

# # IndexError: list index out of range
#
# # 根据元素查索引
# print(name_list.index("李四"))

# 列表元素统计：元素统计
# 场景：结合列表元素去重使用
# 语法格式： 列表名.count(元素)
# 注意事项：
# 统计某元素出现的次数，如果元素不存在，返回0
# 定义列表
# data_list = ['python', 'java', 'python', 'php']
# num = data_list.count("python")
# print(num)
# print(data_list.count("java"))
# print(data_list.count("c++"))
# 结论：
# 统计列表元素出现的次数
# 元素不存在统计结果为0


# 列表元素增加：末尾增加元素
# 语法格式： 列表名.append(元素)
# 注意事项：
# 列表类型属于可变类型，新增元素后，对原有数据进行了修改
# 增加元素默认会增加到列表的末尾 ,每次增加一个
# 定义列表
# val_list = ["Web自动化", "UI自动化", "接口自动化"]
# val_list.append("APP自动化")
# print(val_list)
# val_list.append(11)
# print(val_list)
# 结论：
# 列表属于可变数据类型，增加元素后，原有的列表的值会发生变化
# 追加元素每次只能追加1个，而且每次追加的位置在列表的末尾

# 列表元素增加：指定位置增加元素
# 语法格式： 列表名.insert(下标,元素)
# 注意事项：
# 使用不存在的索引时，会将数据插入列表的末尾
# 定义列表
# val_list = ["Web自动化", "UI自动化", "接口自动化"]
# val_list.insert(1,"APP自动化")
# print(val_list)
# val_list.insert(7,"java")
# print(val_list)
# 结论：
# 指定的位置如果存在，按照指定位置插入元素；如果不存在，默认添加到列表的末尾


# 列表的合并
# 语法格式1： 列表名1.extend(列表名2)
# 语法格式2： 列表1 + 列表2
# 注意事项：
# 传入的数据是列表，直接将列表每个元素追加到第一个列表中
# 传入的数据是字符串，会将字符串中每个字符追加到第一个列表中
# 定义列表
# info1 = [1,2,3]
# info2 = [4,5,6]
# info1.extend(info2)
# print(info1)
# print(info2)


# 列表元素删除：指定索引位置删除🏴
# 语法格式： 列表名.pop(索引)
# 注意事项：
# 删除不传入索引时，默认删除列表最后一个数据（元素）
# 删除传入的索引不存在（超出范围）时，代码报错
# 定义列表
# val_list = ["Web自动化", "APP自动化", "UI自动化", "接口自动化", "java"]
# val_list.pop(2)
# print(val_list)
# val_list.pop()
# print(val_list)
# val_list.pop(7)
# print(val_list)
# 结论：
# 1.下标存在直接按照指定下标删除;如果下标不存在，直接报错
# 2.如果下标不写，默认删除最后一个元素


# 列表元素删除：指定数据删除
# 语法格式： 列表名.remove(元素)
# 注意事项：
# 列表中存在多个该元素使，删除第一个匹配到的
# 如果删除的元素在列表不存在，代码会报错
# 定义列表
# val_list = ["Web自动化", "APP自动化", "java", "UI自动化", "接口自动化", "java"]
# val_list.remove('APP自动化')
# print(val_list)
# val_list.remove('java')
# print(val_list)
# val_list.remove('python')
# print(val_list)
# 总结：
# 1. 如果元素存在直接删除，如果存在多个元素默认删除第一个匹配到的
# 2. 如果元素不不存在直接删除，报错


# 列表元素修改：修改指定索引的数据🏴
# 应用场景：对于列表中某个数据进行更新时使用
# 语法格式： 列表名[索引]=新数据
# 注意事项：
# 指定索引存在，则该位置的元素被修改，如果不存在，则代码报错
# 定义列表
# val_list = ["Web自动化", "UI自动化", "接口自动化", "APP自动化"]
# val_list[1] = "性能自动化"
# print(val_list)
# val_list[5] = "python"
# print(val_list)
# 结论
# 1.下标存在直接修改对应位置的元素；下标不存在直接报错


# 列表元素反转：元素倒置（反转）
# 语法格式： 列表名.reverse()
# 注意事项：
# 对列表数据进行倒置排列
# 定义列表
# info = [8, 100, 30, 110, 40, 2]
# info.reverse()
# print(info)


# 列表元素排序：大小排列🏴
# 应用场景：针对部分面试题会出现
# 语法格式： 列表名.sort(reverse=False)
# 注意事项：
# 对列表元素默认从小到大排序，即reverse=False
# 对列表元素从大到小排序，需要修改reverse=True
# 定义列表
# info = [8, 100, 30, 110, 40, 2]
# info.sort(reverse=False)
# print(info)
# info.sort(reverse=True)
# print(info)
# 结论：
# 1.sort内部有常见两个参数，key:表示按照哪个指标排序（key的值必须是一个函数），reverse:表示排序规则（升序/降序）
# 2.reverse=False表示升序（默认可以不写）；如果reverse=True表示降序


# 列表的嵌套元素获取：列表中的元素还是列表🏴
# 应用场景：针对于多层列表中指定元素获取时使用
# 注意事项：
# 列表元素本身也可以是列表，列表嵌套依旧可以用下标查询元素
# 定义列表
# 列表中的元素还是列表：列表嵌套
# student_list = [["张三", "18", "功能测试"], ["李四", "20", "自动化测试"], ["王五", "22", ["python", "java"]]]
# print(student_list[0])
# aa = student_list[0]
# print(aa[1])
# print(student_list[0][1])
# print(student_list[1][0])
# print(student_list[2][2][1])


# 列表的嵌套：列表中的元素还是列表
# 登录页面为例
# 需求：分别使用不同的数据（包括手机号、密码、验证码）进行登录验证
# 结果：账号或密码错误；验证码错误；登录成功
# 定义非空列表(把每种测试结果的数据放在一起)
# login_data = [
#     ["13488888888", "123456", "8888"],
#     ["13488888888", "666666", "8888"],
#     ["13488888880", "123456", "8888"],
#     ["13488888888", "123456", "0000"]
# ]
# for i in login_data:
#     print(i)
#     if i [0] == "13488888888" and i [1] == "123456":
#         if i [2] == "8888":
#             print("登录成功")
#         else:
#             print("验证码错误")
#     else:
#         print("用户名或密码错误")



# 元组的定义
# 空元组：
# 用()定义： 元组变量名 = ()
# 类实例化方式定义： 元组变量名 = tuple()
# 非空元组：
# 元组变量名 = (元素1,元素2,...)
# 元组变量名 = 元素1,元素2,...
# 注意事项
# 元组的元素有多个时，小括号可以不写
# 元组只有一个元素时，写小括号，且元素后面加逗号： (元素,)
# 定义空元组
# info = ()
# info1 = tuple()
# print(info)
# print(info1)
# # 非空
# info2 = (11, 22, 33, 44)
# print(info2)
# info3 = ("55")
# print(type(info3))
# info4 = 1, 2, 3, 4
# print(type(info4))
# 结论：
# 1. 元组的括号可以省略
# 2. 元组是一个元素值时，需要在元素后面加逗号



# 元组的使用
# 元组元素查询：索引
# 语法格式： 元组名[索引]
# 注意事项：
# 结果返回的元组元素的索引（也叫下标），默认从0开始
# 如果查询的索引不存在，则代码会报错
# 定义元组
# info = (11, "aaa", 1.88)
# print(info[2])
# print(info[4])
# 总结：
# 1.如果下标存在，直接查询对应位置的元素；下标不存在直接报错




# 元组元素查询：元素统计
# 语法格式： 元组名.count(元素)
# 注意事项：
# 统计某元素出现的次数，如果元素不存在，返回0
# 定义元组
# info = (1, 2, 3, 2)
# print(info.count(2))
# print(info.count(3))
# print(info.count(4))




# 元组其他应用：数据交换
# 应用场景：常常用做两组数据的直接互换
# 可以直接交互原因
# Python定义多个元素的元组数据时，小括号可以省略
# Python对应元素变量可以获取元组中每个元素的值
# 定义变量
# num1 = 100
# num2 = 200
# tmp = num1
# num1 = num2
# print("此时num1的值：", num1)
# print("此时num2的值：", num2)
# 方式2：直接借助于python元组类型的数据直接替换
# aa = 200
# bb = 100
# num1 = aa
# num2 = bb
# num1, num2 = num2, num1
# print("此时num1的值是：", num1)
# print("此时num1的值是：", num2)


# 元组和列表区别
# 面试题：请问列表和元组的区别？
# 表示形式不同，元组用小括号，列表用中括号；
# 表示单个元组元素时，元素后必须加 ,
# 操作数据本质不同，元组是不可变数据类型，列表是可变数据类型
# 字典的定义
# 空字典：
# 用{}定义： 字典变量名 = {}
# 类实例化方式定义： 字典变量名 = dict()
# 非空字典【常见】：
# 字典变量名 = {键1:值1,键2:值2,...}
# 注意事项
# 字典中的键一般使用字符串，其中键名不能重复（重复了数据会被覆盖）
# 字典中的数据俗称“键值对”

# 定义空字典
# info = {}
# info1 = {}
# print(info)
# print(info1)
# 非空字典
# info2 = {"name": "张三", "age": 22, "height": 1.88}
# print(info2)
# print(type(info2))
# 结论：
# 1.键名不能重复
# 2.键的数据类型可以任意（推荐用字符串）


# 字典的使用🏴
# 字典新增或修改值
# 语法格式： 字典名[键]=值
# 注意事项：
# 字典中键存在则修改值，键不存在则新增值
# # 定义非空字典
# info = {"name": "张三"}
# info["name"] = "李四"
# print(info)
# info["age"] =22
# print(info)
# 结论：
# 1.字典中键存在修改值，不存在新增键和值



# 字典删除值
# 语法格式： 字典名.pop(键)
# 注意事项：
# 键存在删除对应值，键不存在，则代码报错
# 定义字典
# info ={'name': '李四', 'age': 22}
# info.pop("age")
# print(info)
# info.pop("set")
# print(info)
# 结论：
# 1.键存在直接删除对应键和值，键不存在报错


# 字典中取值🏴
# 语法格式：
# 格式1： 变量 = 字典名[键]
# 格式2： 变量 = 字典名.get(键)
# 注意事项：
# 格式1键存在返回对应值，键不存在，则代码报错
# 格式2键存在返回对应值，键不存在，则返回None（空值）
# 定义非空字典
# info = {
#     "name": "tom",
#     "age": 18,
#     "gender": "男",
#     "hobby": {"read": "小说", "sport": ["篮球", "足球"]}
# }
# # 查询年龄
# a1 = info["age"]
# print(a1)
# print(info["age"])
# a2 = info.get("age")
# print(a2)
# print(info.get("age"))
# 查询键aa的值
# print(info["aa"])
# print(info.get("aa"))
# 思考：如何获取值："足球"
# a1 = info["hobby"]
# print(a1)
# print(a1["sport"])
# print(a1["sport"][1])
# print(info["hobby"]["sport"][1])
# print(info.get("hobby").get("sport")[1])
# 结论：
# 1.键存在，两个方法无区别，如果键不存在，get方法直接返回None，但是通过键直接查询会报错



# 字典的合并/新增
# 语法格式： 字典2.update(字典1)
# 注意事项：字典2中如果存字典1的键则被更新，否则被新增
# 定义字典1
# dict1 = {"name": "张三", "age": 18}
# dict2 = {"height": 1.88}
# dict1.update(dict2)
# print(dict1)



# 字典的遍历🏴
# 遍历：从容器中重复(一个又一个)的获取数据的过程
# 遍历字典键：
# 语法格式： for 临时变量 in 字典名.keys():
# 说明：取出字典中的所有键，容器后面可以不写 .keys()
# 遍历字典值：
# 语法格式： for 临时变量 in 字典名.values():
# 说明：取出字典中的所有值
# 遍历键和值：
# 语法格式： for 键变量,值变量 in 字典名.items():
# 说明：取出字典中的所有键和值


# 定义非空字典
# info = {
#     "name": "tom",
#     "age": 18,
#     "gender": "男"
# }
# for i in info.keys():
#     print(f"字典的键是：{i}")
# for i in info.values():
#     print(f"字典的值是：{i}")
# for k, v in info.items():
#     print(f"{k} = {v}")



# 集合的定义
# 空集合：
# 类实例化方式定义： 变量名 = set()
# 非空集合：
# 集合变量名 = {值1,值2,...}
# 集合的使用
# 集合元素添加
# 语法格式： 集合.add(元素)
# 列表元素去重
# 语法格式： 变量 = set(列表名)
# 1.定义空集合
# info = set()
# print(info)
# 2.集合中添加元素："a"
# info.add("a")
# info.add("b")
# print(info)
# 定义非空字符串
# var = "abcdefg"
# 3.打印非重复的元素
# print(set(var))
# tem = list(set(var))
# tem.sort()
# print(tem)
# print("".join(tem))

# 3.1切片操作
# 作用：取出序列中一部分（一段）数据【数据类型不变】，以字符串、列表、元组为主
# 语法格式： 变量名[start:end:step]
# start：切片开始下标
# end：切片结束下标
# step：切片步长【可选】
# 注意事项：
# 下标: "顾头不顾尾"
# start：开始下标(包含)；end：结束下标(不包含)；step：截取步长,默认为1,可以省略
# start,end,step可以省略不写,支持正向索引和逆向索引
# 正向索引：步长为正数，从左向右
# 负向索引：步长为负数，从右向左
# 作用：按照指定要求获取一段数据
# 定义非空字符串
# name = "abcdefgh"
# print(name[2:5])
# print(name[2:5:1])
# print(name[-6:-3])
# print(name[-6:-3:-1])
# print(name[3:8])
# print(name[3:])
# print(name[-5:])
# print(name[0:5:2])
# print(name[:5:2])
# print(name[::-1])


# 3.2 序列长度🏴
# 应用场景：常常应用于对后台返回数据进行统计某个对象数据的长度
# 作用：计算序列的长度（统计元素的个数）
# 语法格式： len(变量名)
# 定义非空字符串
# info = "abcdefgh"
# info1 = "Hello Python"
# print(len(info))
# print(len(info1))
# 定义非空列表
# info2 = [11, "aa", 1.88, (1, 2, 3), ["aa", "bb"]]
# print(len(info2))
# 定义非空元组
# info3 = (11, "aa", 1.88)
# print(len(info3))
# 定义非空字典
# info4 = {"name": "tom", "age": 18, "gender": "男"}
# print(len(info4))
# 结论：
# 1.字典元素统计按照键值对统计

# 3.3 清空序列
# 作用：清空序列中所有数据，以列表和字典为主（支持可变数据类型清空）
# 语法格式： 变量名.clear()
# info2 = [11, "aa", 1.88, (1, 2, 3), ["aa", "bb"]]
# info2.clear()
# print(info2)
# info4 = {"name": "tom", "age": 18, "gender": "男"}
# info4.clear()
# print(info4)
# 结论：只针对可变数据类型可以做清空